//
//  ptranal.cpp
//  ltlbmc
//
//  Created by GD Huang on 8/27/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#include <iostream>
#include <vector>

#include "ptranal.h"
#include "ast.h"

extern "C" {
#include <caml/mlvalues.h>
#include <assert.h>
    
#include "cil_type.h"
#include "cil_stub.h"
#include "cil_wrap.h"
    
}

template <typename T>
std::vector<T*> copyArray(value list, T* (*functor)(value));

template<class T>
T* symbolTableLookup(value v) {
    if(symbolTable.find(v)!=symbolTable.end()) {
        return (T*)symbolTable[v];
    } else {
        return NULL;
    }
}


namespace cilast {


    
    static ptranal instance() {
        static ptranal singleInstance;
        return singleInstance;
    }
    
    void ptranal::analysis_file(file* f) {
        static bool called = false;
        
        if(!called) {
            //Points-to Analysis
            Ptranal_analyze_file(f->sink);
            called = true;
        }
        
    }

    bool ptranal::may_alias(exp* e1, exp* e2) {
        value result = Ptranal_may_alias(e1->sink, e2->sink);
        return Bool_val(result);
    }
    
    std::vector<varinfo*> ptranal::resolve_lval(lval* l) {
        value varinfoList = Ptranal_resolve_lval(l->sink);
        std::vector<varinfo*> result = copyArray(varinfoList, &symbolTableLookup<varinfo>);
        return result;
    }
    
    
    std::vector<varinfo*> ptranal::resolve_exp(exp* e) {
        value varinfoList = Ptranal_resolve_exp(e->sink);
        std::vector<varinfo*> result = copyArray(varinfoList, &symbolTableLookup<varinfo>);
        return result;
    }
    
    
    std::vector<fundec*> ptranal::resolve_funptr(exp* e) {
        value fundecList = Ptranal_resolve_funptr(e->sink);
        std::vector<fundec*> result = copyArray(fundecList, &symbolTableLookup<fundec>);
        return result;
    }
    
}
